package com.camundademo.rest.controller;


import cn.hutool.core.date.DateTime;
import com.camundademo.modole.dto.DefineFlowInput;
import com.camundademo.rest.dto.Results;
import com.camundademo.rest.service.CamundaFlowService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.camunda.bpm.engine.rest.dto.repository.DeploymentDto;
import org.camunda.bpm.engine.rest.dto.repository.DeploymentQueryDto;
import org.camunda.bpm.engine.rest.dto.repository.DeploymentResourceDto;
import org.camunda.bpm.engine.rest.dto.repository.DeploymentWithDefinitionsDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * 1. camunda中流程定义通常是在 Camunda Modeler这样的建模工具中完成，也可以手动编写XML文件，
 * 或者使用图形化界面在Camunda的Web应用程序中完成 。即产出bpmn文件 :可以保存在boot3/camundademo/bpmn文件夹下
 * 2. 通过camunda的rest api 部署到camunda中
 */

@RestController//ResponseBody需要和 @Controller结合使用  RestController的每个方法都是按有ResponseBody执行的  就是出参处理不一样 入参处理是一样的
@RequestMapping("/deploymentCtrl")
public class CamundaDeploymentCtrl {


    @Autowired
    private CamundaFlowService camundaFlowService;

    //CamundaBpmWebappInitializer camunda提供的webapp初始化类 定义的一些api基础路径
    /*用来检测工作流服务状态
    get    /engine-rest/deployment?maxResults=0  接口正常 就是服务状态正常
     * */

    /*查看工作流版本
    get    /engine-rest/version
     * */

    /*camunda提供的部署api
    post    /engine-rest/deployment/create
     * */

    /**
     * DefaultProcessEngineRestServiceImpl 默认的流程引擎的各种Rest服务
     * CamundaRestResources  camunda的各种Rest服务注册 可以查到
     */

    /**
     * deploy222
     *
     * @return
     */
    @PostMapping(
            //指定URL 路径
            value = "/deploy222",
            name = "部署流程接口test",
            //用于指定可接受的请求体媒体类型。可以用于限制请求体的媒体类型，
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Results<TEstDto> deploy222(
            TEstDto estDto,
            @RequestParam(required = false)
            Integer firstResult
                                     ) {

        //System.out.println(genericConversionService);
        System.out.println(estDto);
        estDto.setDate2(DateTime.now());

        System.out.println(estDto);
        return Results.ok(estDto);
    }

    @Data
    public static class TEstDto {
        Date date;
        Date date2;
    }

    /**
     * 部署的接口
     *
     * @param defineFlowInput
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/deploy",
                 //生成文档或进行逻辑分组
                 name = "部署流程接口",
                 consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Results<DeploymentWithDefinitionsDto> deploy(
            @Validated
            DefineFlowInput defineFlowInput
                                                       ) throws IOException {
        //参数校验完成送入服务层
        DeploymentWithDefinitionsDto deploy = camundaFlowService.deploy(defineFlowInput);
        //包装返回值
        return Results.ok(deploy);
    }

    /**
     * 删除部署记录接口
     * 参考camunda的 DeploymentResource.deleteDeployment
     */
    @PostMapping(value = "/delDeploy",
                 name = "删除部署记录接口",
                 consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Results<String> delDeploy(
            @Validated
            @NotBlank(message = "deploymentId不能空")
            @RequestParam
            String deploymentId
                                    ) throws IOException {
        //参数校验完成送入服务层
        System.out.println(deploymentId);
        camundaFlowService.delDeploy(deploymentId);
        //包装返回值
        return Results.ok(null);
    }

    /**
     * 查询部署记录接口
     * 参考camunda的openapi  /deployment实现 带分页
     * sortBy; 字段名
     * sortOrder; desc/asc
     */

    @PostMapping(value = "/queryDeploy",
                 //生成文档或进行逻辑分组
                 name = "查询部署记录接口",
                 consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    //参考camunda提供的 DeploymentRestService.getDeployments
    public Results<List<DeploymentDto>> queryDeploy(
            //sortBy=id&sortOrder=desc
            DeploymentQueryDto deploymentQueryDto,
            @RequestParam(required = false)
            Integer firstResult,
            @RequestParam(required = false)
            Integer maxResults
                                                   ) throws IOException {
        //参数校验完成送入服务层
        List<DeploymentDto> deploymentDtos = camundaFlowService.queryDeploy(
                deploymentQueryDto, firstResult, maxResults);
        //包装返回值
        return Results.ok(deploymentDtos);
    }


    /**
     * 部署记录中的资源  仿照queryDeploy 参考sql日志实现
     */
    @PostMapping(value = "/getDeploymentResources",
                 name = "部署记录中的资源",
                 consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Results<List<DeploymentResourceDto>> getDeploymentResources(
            @NotBlank(message = "deploymentId不能空")
            @RequestParam(required = false,
                          defaultValue = "")
            String deploymentId
                                                                      ) throws IOException {
        //参数校验完成送入服务层
        System.out.println(deploymentId);
        List<DeploymentResourceDto> deploymentRes = camundaFlowService.getDeploymentResources(deploymentId);
        //包装返回值
        return Results.ok(deploymentRes);
    }


    /**
     * 部署的资源文件通过id  参考sql日志实现
     */
    @PostMapping(value = "/getResourceAsStreamById",
                 name = "部署的资源文件通过id",
                 consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public void getResourceAsStreamById(
            @NotBlank(message = "deploymentId不能空")
            @RequestParam(required = false)
            String deploymentId,

            @NotBlank(message = "resourcesId不能空")
            @RequestParam(required = false)
            String resourcesId,
            // HttpServletRequest request,
            HttpServletResponse response
                                       ) throws IOException {
        //参数校验完成送入服务层
        System.out.println(deploymentId);
        System.out.println(resourcesId);

        //包装返回值
        // return Results.ok(null);
        Results.responseDoOutputStream(response, camundaFlowService.getResourceAsStreamById(deploymentId, resourcesId));
    }
}
